package zdream.control.test.avatars.mm;

import org.junit.Before;
import org.junit.Test;

import zdream.control.foe.mm.MegaMan;
import zdream.control.input.SimpleWorldInput;
import zdream.control.input.WorldInput;
import zdream.control.region.Region;
import zdream.control.region.SimpleRegionBuilder;
import zdream.control.world.LevelWorld;

import static org.junit.Assert.*;

/**
 * @author Zdream
 * @date 2023-12-26
 * @since 0.0.1
 */
public class MoveCase {
	Region region;

	@Before
	public void prepare() {
		region = new SimpleRegionBuilder(this.getClass().getSimpleName())
				.withRoomPositions("1")
				.withRoom(1)
						.terrain("#########################")
						.terrain("#########################")
						.terrain("##                     ##")
						.terrain("##                     ##")
						.terrain("##                     ##")
						.terrain("##                     ##")
						.terrain("##                     ##")
						.terrain("##                     ##")
						.terrain("##                     ##")
						.terrain("##                     ##")
						.terrain("##                     ##")
						.terrain("#########################")
						.terrain("#########################")
						.terrain("#########################")
						.build()
				.build();
		assertEquals(1, region.rooms.length);
	}

	@Test
	public void testDrop() {
		LevelWorld world = new LevelWorld();
		world.setCurrentRoom(region.rooms[0]);

		SimpleWorldInput input = new SimpleWorldInput();

		MegaMan mm = new MegaMan(world);
		world.createFoe(mm, 12, 8, true);
		assertEquals(1, world.foes.size());

		mm.putInput(input);
		assertEquals(12, mm.anchorX, 0);
		assertEquals(8, mm.anchorY, 0);

		// 应该是会自由落体
		world.render(1 / 60f);
		assertTrue(mm.inAir);
		assertEquals(12, mm.anchorX, 0);
		assertTrue(8 > mm.anchorY);
		float lastY = mm.anchorY;
		System.out.println(mm);

		world.render(1 / 60f);
		assertTrue(mm.inAir);
		assertEquals(12, mm.anchorX, 0);
		assertTrue(lastY > mm.anchorY);
		System.out.println(mm);

		long startTime = world.ticker.activeTime;
		while (lastY != mm.anchorY) {
			lastY = mm.anchorY;
			world.render(1 / 60f);
			System.out.println(mm);
		}

		long elapsed = world.ticker.activeTime - startTime;
		System.out.printf("经过 %d ms, 从高度 8 降落到高度为 %f 的地面上%n", elapsed, mm.anchorY);
		assertFalse(mm.inAir);
		assertEquals(12, mm.anchorX, 0);
	}

	@Test
	public void testJump() {
		LevelWorld world = new LevelWorld();
		world.setCurrentRoom(region.rooms[0]);

		SimpleWorldInput input = new SimpleWorldInput();

		MegaMan mm = new MegaMan(world);
		world.createFoe(mm, 12, 3, true);
		assertEquals(1, world.foes.size());

		mm.putInput(input);
		assertEquals(12, mm.anchorX, 0);
		assertEquals(3, mm.anchorY, 0);
		world.render(1 / 60f);

		for (int i = 1; i < 30; i++) {
			System.out.printf("测试按住 %d 帧之后, 最高能跳多高%n", i);

			float maxY = mm.anchorY;
			input.setDown(WorldInput.MAP_JUMP);
			for (int j = 0; j < i; j++) {
				world.render(1 / 60f);
				maxY = Math.max(maxY, mm.anchorY);
			}

			input.setUp(WorldInput.MAP_JUMP);
			for (int j = 0; j < 100; j++) {
				world.render(1 / 60f);
				if (mm.anchorY == 3) {
					break;
				}
			}
			assertEquals(3, mm.anchorY, 0);
			System.out.printf("测试按住 %d 帧之后, 最高跳 %f%n", i, maxY);
		}
	}
}
